//
//
// adventure screen handler for the Treasure Chest Object
//
// L. Dean Gibson II  2/20/01
//

#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "adv_treasure_chest.h"

#include "adv_object_model.h"
#include "adventure_frame.h"
#include "adventure_map.h"
#include "adventure_sounds.h"
#include "ai_value.h"
#include "army.h"
#include "artifact_properties.h"
#include "artifact_type.h"
#include "basic_dialog.h"
#include "bitmap_layer_cache_window.h"
#include "bitmap_layer_cache_window_ptr.h"
#include "counted_ptr.h"
#include "default_artifacts.h"
#include "external_string.h"
#include "hero.h"
#include "materials.h"
#include "music.h"
#include "object_registration.h"
#include "player.h"
#include "random.h"
#include "replace_keywords.h"
#include "treasure_chest_window.h"

static t_object_registration<t_adv_treasure_chest> k_registration( k_adv_object_treasure,
																   k_treasure_treasure_chest );

// -------------------------------------------------------
// Treasure Chest object constructor
// -------------------------------------------------------
t_adv_treasure_chest::t_adv_treasure_chest( std::string const& model_name )
			  : t_stationary_adventure_object( model_name )
{
	m_artifact = k_artifact_none;
}

void t_adv_treasure_chest::give_artifact( t_army* army, t_level_map_point_2d point, 
		                                  t_direction direction, t_adventure_frame* frame)
{
	t_artifact new_artifact;

	new_artifact = get_default_artifact(m_artifact);

	// give the decided artifact to the hero in the army, if any
	if (army->get_owner()->is_computer())
	{
		ai_give_artifact_to_army( *army, new_artifact );
		return;
	}
	else 
		army->add(new_artifact);

	// display some sort of response 

	t_basic_dialog*					dialog;
	std::string						text;

	dialog = new t_basic_dialog;
    dialog->set_title( get_text( "name" ) );
	text = get_text( "Artifact" );
	text = replace_keywords(text, "%an_artifact", new_artifact.get_name( true ));
	// add the artifact's name to the displayed text
	dialog->set_text( text );
	dialog->add_artifact( new_artifact );
	dialog->add_ok_button();

	dialog->open( get_dialog_bottom( point ), true, k_align_bottom );
	t_sound_cache music = get_music_playing();
	stop_music();
	get_dialog_sound( k_dialog_sound_treasure_chest )->play( get_sound_volume() );
	dialog->run_modal();
	play_music( music );
}

void t_adv_treasure_chest::give_gold( t_player* player, t_level_map_point_2d point )
{
	player->gain(k_gold, m_chest_gold);
	
	if (player->is_computer())
		return;

	// display simple dialog of such
	t_basic_dialog*	dialog;
	std::string		text;

	dialog = new t_basic_dialog;
    dialog->set_title( get_text( "name" ) );
	text = get_text("creature_gold");
	text = replace_keywords(text, m_chest_gold, k_gold);
	// add the artifact's name to the displayed text
	dialog->set_text( text );
	dialog->add_material( k_gold, m_chest_gold );			
	dialog->add_ok_button();
	dialog->open( get_dialog_bottom( point ), true, k_align_bottom );
	t_sound_cache music = get_music_playing();
	stop_music();
	get_dialog_sound( k_dialog_sound_treasure_chest )->play( get_sound_volume() );
	dialog->run_modal();
	play_music( music );
}

// -------------------------------------------------------
// activate trigger for the Treasure Chest adventure map object
// -------------------------------------------------------
void t_adv_treasure_chest::activate_trigger( t_army* army, t_adv_map_point const& point, 
		                               t_direction direction, t_adventure_frame* frame )
{
	int								  chest_return_value;
	t_player *						  player = army->get_owner();

    bool upgradable_hero = false;

	for (int i = 0; i < t_creature_array::k_size; i++)
	{
		t_hero* hero = (*army)[i].get_hero();

        // Not a hero.
        if (!hero)
            continue;

        // Dead.
        if (hero->is_dead())
            continue;

        // Can't add any more experience.
	    if (!(hero->can_add_experience( player )))
            continue;
        
        upgradable_hero = true;
    }

	if (m_chest_gold == 0)
	{ // we got an artifact here!
		give_artifact( army, point, direction, frame );
	}
	else if ((army->get_living_hero_count() == 0) || (!upgradable_hero))
	{ // no heroes in the army.. just give the gold
		give_gold( player, point );
	} 
	else 
	{
		t_player* player = army->get_owner();
		
		if (!player->is_computer())
		{
			t_counted_ptr<t_treasure_chest_window> dialog 
				= new t_treasure_chest_window(frame, this);

			t_sound_cache music = get_music_playing();
			stop_music();
			get_dialog_sound( k_dialog_sound_treasure_chest )->play( get_sound_volume() );
			chest_return_value = dialog->run_modal();
			play_music( music );

			if (chest_return_value == 0) { // player wants to take the gold
				player->gain(k_gold, m_chest_gold);
			} 
			else 
			{ // player wants to give gold to peasants and gain the experience!
				// give heroes gp-500 exp, if more than one hero, divide equally amongst them all
				int	 exp_award = m_chest_gold - 500;

				army->get_creatures().add_experience( exp_award, frame, true );
			}
		}
		else 
		{ 
			int exp_award = m_chest_gold - 500;
			float value_of_gold = player->get_material_value( k_gold ) * m_chest_gold;
			float value_of_xp = ai_value_of_xp( army, exp_award );
			if (value_of_gold > value_of_xp)
				player->gain(k_gold, m_chest_gold);
			else
				army->add_experience( exp_award, 0, true ); 
		}
	}
	destroy(); // remove us from the map

	// update the frame
	frame->update();
}

// -------------------------------------------------------
// Treasure Chest as it is placed...
// -------------------------------------------------------
void t_adv_treasure_chest::initialize( t_adventure_map& map )
{
	int die;

	// roll the die see how much gold, or if there is an item in this treasure chest

	die = random(10);
	switch (die) {
	case 0:
	case 1:
	case 2:
		m_chest_gold = 1000;
		break;
	case 3:
	case 4:
	case 5:
		m_chest_gold = 1500;
		break;
	case 6:
	case 7:
	case 8:
		m_chest_gold = 2000;
		break;
	case 9:
		m_artifact = map.get_random_artifact(k_artifact_level_treasure);
		m_chest_gold = 0;
		break;
	default:
		m_chest_gold = 1000; // error! just make it some gold then...
		break;
	};
}

// -------------------------------------------------------
// Treasure Chest as it appears on the adventure map
// -------------------------------------------------------
bool t_adv_treasure_chest::write( std::streambuf& stream ) const
{
	put<t_artifact_type>( stream, m_artifact );
	put<int>( stream, m_chest_gold );
	return true;
}

// -------------------------------------------------------
// Treasure Chest as it appears on the adventure map
// -------------------------------------------------------
bool t_adv_treasure_chest::read( std::streambuf&						stream, 
								 t_qualified_adv_object_type const&	type,
								 int									version )
{
	m_artifact = get<t_artifact_type>( stream );
	m_chest_gold = get<int>( stream );
	return true;
}

// -------------------------------------------------------
// Treasure Chest as it appears on the adventure map
// -------------------------------------------------------
float t_adv_treasure_chest::ai_value( t_adventure_ai const& ai, t_creature_array const& army, int move_cost ) const
{
	t_player* player = army.get_owner();
	// Value of the average gold weighted at 90% (for 9/10 chance) combined
	// with the value of average treasure level weighted at 10% (for 1/10 chance)
	
	return 
		player->get_material_value(k_gold) * 1500 * 0.9f 
		+ player->ai_get_artifact_value(k_artifact_level_treasure) * 0.1f;
}

